package com.ipan.weixin;

import java.util.HashMap;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.ipan.weixin.msg.AbstractJsonMsg;
import com.ipan.weixin.msg.AccessTokenMsg;
import com.ipan.weixin.msg.ErrorMsg;
import com.ipan.weixin.msg.JsonMsg;
import com.ipan.weixin.util.WxHttpUtils;

/**
 * AccessToken管理器
 * 
 * @author iPan
 * @version 2013-12-30
 */
public class AccessTokenManager {

	private static final long DELAY_TIME = 30000;

	private String accessToken;
	
	private long expiresIn = 7200L;
	
	private long flushTime = -1;
	
	private Logger logger = LoggerFactory.getLogger(getClass());
	
	public static final AccessTokenManager INSTANCE = new AccessTokenManager();
	
	private AccessTokenManager() {
		Timer timer = new Timer("access_token_timer", true);
		timer.schedule(new TimerTask() {
			@Override
			public void run() {
				long curTime = System.currentTimeMillis();
				if (curTime - flushTime > (expiresIn - 200) * 1000) {
					flush();
				}
			}}, DELAY_TIME, DELAY_TIME);
	}
	
	public static AccessTokenManager getInstance() {
		return INSTANCE;
	}

	public String getAccessToken() {
		return accessToken;
	}

	public void setAccessToken(String accessToken) {
		this.accessToken = accessToken;
	}

	public Long getExpiresIn() {
		return expiresIn;
	}

	public void setExpiresIn(Long expiresIn) {
		this.expiresIn = expiresIn;
	}
	
	public void flush() {
		String appId = WxConfiguration.getInstance().getAppid();
		String appsecret = WxConfiguration.getInstance().getAppsecret();
		String url = WxConfiguration.getInstance().getUrlToken();
		Map<String, String> paramMap = new HashMap<String, String>();
		paramMap.put("appid", appId);
		paramMap.put("secret", appsecret);
		url = WxConfiguration.fillUrlParam(url, paramMap);
		// 请求公众平台获取accessToken
		String result = WxHttpUtils.get(url);
		this.flushTime = System.currentTimeMillis();
		JsonMsg jsonMsg = null;
		try {
			jsonMsg = AbstractJsonMsg.fromJson(result, AccessTokenMsg.class);
			this.accessToken = ((AccessTokenMsg) jsonMsg).getAccess_token();
			this.expiresIn = ((AccessTokenMsg) jsonMsg).getExpires_in();
		} catch (Exception e) {
			try {
				jsonMsg = AbstractJsonMsg.fromJson(result, ErrorMsg.class);
				Integer errcode = ((ErrorMsg) jsonMsg).getErrcode();
				String errmsg = ((ErrorMsg) jsonMsg).getErrmsg();
				logger.warn("请求失败：{}; errcode:{}, errmsg: {}.", 
						new Object[]{WxConfiguration.getInstance().getStatusValue(errcode), errcode, errmsg});
			} catch (Exception e1) {
				logger.error("消息转换失败：{}.", result);
			}
		}
	}
	
//	public static void main(String[] args) throws InterruptedException {
//		Timer timer = new Timer("access_token_timer", true);
//		timer.schedule(new TimerTask() {
//			@Override
//			public void run() {
//				System.out.println("timer ...");
//			}}, 3000, 1000);
//		Thread.sleep(10000);
//	}
}
